package com.itheima.reggie.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper,Setmeal> implements SetmealService {
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private CategoryService categoryService;
    @Override
    @CacheEvict(value = "SETMEAL_CACHE",allEntries = true)
    public void addSetmeal(SetmealDto setmealDto) {
    this.save(setmealDto);
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        setmealDishes.stream().map(c->{
            c.setSetmealId(setmealDto.getId());
            return c;
        }).collect(Collectors.toList());
        setmealDishService.saveBatch(setmealDishes);
    }

    @Override
    public Page<SetmealDto> findByPage(Integer page, Integer pageSize, String name) {
        IPage<Setmeal> pageInfo = new Page<>(page,pageSize);
        Page<SetmealDto> setmealDtoPage = new Page<>();
        LambdaQueryWrapper<Setmeal> wapper = new LambdaQueryWrapper<>();
        wapper.eq(Setmeal::getIsDeleted,0);
        if(name!=null&&name!=""){
            wapper.like(Setmeal::getName,name);
        }
        wapper.orderByDesc(Setmeal::getUpdateTime);
        pageInfo= this.page(pageInfo, wapper);
        List<Setmeal> setmeals = pageInfo.getRecords();
        List<SetmealDto> setmealDtos = JSON.parseArray(JSON.toJSONString(setmeals),SetmealDto.class);
        setmealDtos.stream().map(c->{
            Long categoryId = c.getCategoryId();
            Category category = categoryService.getById(categoryId);
            if(category != null) {
                c.setCategoryName(category.getName());
            }
            return c;
        }).collect(Collectors.toList());
        setmealDtoPage.setRecords(setmealDtos);
        setmealDtoPage.setTotal(pageInfo.getTotal());
        return setmealDtoPage;
    }

    @Override
    @Transactional
    @CacheEvict(value = "SETMEAL_CACHE",allEntries = true)
    public void deleteByIds(Long[] ids) {
        List<Setmeal> setmeals = this.listByIds(Arrays.asList(ids));
        setmeals =setmeals.stream().map(c->{
            c.setIsDeleted(1);
            return c;
        }).collect(Collectors.toList());
        this.updateBatchById(setmeals);
        setmeals.stream().map(c->{
            LambdaQueryWrapper<SetmealDish> setmealDishWapper = new LambdaQueryWrapper<>();
            setmealDishWapper.eq(SetmealDish::getSetmealId,c.getId());
            List<SetmealDish> setmealDishList = setmealDishService.list(setmealDishWapper);
            setmealDishList =setmealDishList.stream().map(m->{
                m.setIsDeleted(1);
                return m;
            }).collect(Collectors.toList());
            setmealDishService.updateBatchById(setmealDishList);
            return c;
        }).collect(Collectors.toList());
    }

    @Override
    public SetmealDto findById(Long id) {
        Setmeal setmeal = this.getById(id);
        SetmealDto setmealDto = new SetmealDto();
        BeanUtils.copyProperties(setmeal,setmealDto);
        LambdaQueryWrapper<SetmealDish> wapper = new LambdaQueryWrapper<>();
        wapper.eq(SetmealDish::getSetmealId,id);
        List<SetmealDish> setmealDishes = setmealDishService.list(wapper);
        setmealDto.setSetmealDishes(setmealDishes);
        return setmealDto;
    }

    @Override
    @CacheEvict(value = "SETMEAL_CACHE",allEntries = true)
    public void updateSetmeal(SetmealDto setmealDto) {
        this.updateById(setmealDto);
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        setmealDishes = setmealDishes.stream().map(c->{
          c.setSetmealId(setmealDto.getId());
          return c;
        }).collect(Collectors.toList());
        LambdaUpdateWrapper<SetmealDish> wapper = new LambdaUpdateWrapper<>();
        wapper.eq(SetmealDish::getSetmealId,setmealDto.getId());
        setmealDishService.remove(wapper);
        setmealDishService.saveOrUpdateBatch(setmealDishes);
    }

    @Override
    @CacheEvict(value = "SETMEAL_CACHE",allEntries = true)
    public void updateByStatus(Integer status, Long[] ids) {
        List<Setmeal> setmeals = this.listByIds(Arrays.asList(ids));
        setmeals.stream().map(c->{
            c.setStatus(status);
            return c;
        }).collect(Collectors.toList());
        this.updateBatchById(setmeals);
    }
@Cacheable(value = "SETMEAL_CACHE",key = "'SETMEAL'+#setmeal.categoryId+'_'+#setmeal.status")
    @Override
    public List<Setmeal> findByQpage(Setmeal setmeal) {
        LambdaQueryWrapper<Setmeal> wapper = new LambdaQueryWrapper<>();
        wapper.eq(Setmeal::getCategoryId,setmeal.getCategoryId());
        wapper.eq(Setmeal::getStatus,setmeal.getStatus());
        List<Setmeal> setmeals = this.list(wapper);
        return setmeals;
    }
}
